import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
import { Button, Input, Select } from 'antd';
import React, { useMemo } from 'react';
import { useContextSelector } from 'use-context-selector';

import FormLabel from '@/components/MyBox/FormLabel';
import QuestionTip from '@/components/tooltip/QuestionTip';
import { t } from '@/locales/i18n';
import { getNanoid } from '@/pages/chat/tools/tools';
import {
  AllFlowValueTypeMap,
  FlowNodeOutputTypeEnum,
  FlowValueTypeMap,
  NodeOutputKeyEnum,
  WorkflowIOValueTypeEnum,
} from '@/types/workflow/constant';
import { FlowNodeOutputItemType } from '@/types/workflow/io';

import { WorkflowContext } from '../../../../context';

import { defaultOutput } from './FieldEditModal';
import OutputLabel from './Label';
import { RenderOutputProps } from './type';

// import { defaultOutput } from './FieldEditModal';

// const FieldEditModal = dynamic(() => import('./FieldEditModal'));

const RenderList: {
  types: FlowNodeOutputTypeEnum[];
  Component: React.ComponentType<RenderOutputProps>;
}[] = [];

const RenderOutput = ({
  nodeId,
  flowOutputList,
}: {
  nodeId: string;
  flowOutputList: FlowNodeOutputItemType[];
}) => {
  const onChangeNode = useContextSelector(WorkflowContext, (v) => v.onChangeNode);

  const outputString = useMemo(() => JSON.stringify(flowOutputList), [flowOutputList]);
  const copyOutputs = useMemo(() => {
    return JSON.parse(outputString) as FlowNodeOutputItemType[];
  }, [outputString]);

  // 将嵌套的useMemo提取到外层
  const dynamicOutputs = useMemo(() => {
    return copyOutputs.filter((item) => item.type === FlowNodeOutputTypeEnum.dynamic);
  }, [copyOutputs]);

  const addOutput = useMemo(() => {
    return dynamicOutputs.find((item) => item.key === NodeOutputKeyEnum.addOutputParam);
  }, [dynamicOutputs]);

  const filterAddOutput = useMemo(() => {
    return dynamicOutputs.filter((item) => item.key !== NodeOutputKeyEnum.addOutputParam);
  }, [dynamicOutputs]);

  const showValueTypeSelect = useMemo(() => {
    if (
      !addOutput?.customFieldConfig?.selectValueTypeList ||
      addOutput?.customFieldConfig?.selectValueTypeList.length <= 1
    )
      return false;

    return true;
  }, [addOutput?.customFieldConfig?.selectValueTypeList]);

  const valueTypeSelectList = useMemo(() => {
    if (!addOutput?.customFieldConfig?.selectValueTypeList) return [];

    const dataTypeSelectList = Object.values(FlowValueTypeMap)
      .slice(0, -1)
      .map((item) => ({
        label: t(item.label as any),
        value: item.value,
      }));

    return dataTypeSelectList.filter((item) =>
      addOutput?.customFieldConfig?.selectValueTypeList?.includes(item.value),
    );
  }, [addOutput?.customFieldConfig?.selectValueTypeList]);

  const RenderDynamicOutputs = useMemo(() => {
    const changeOutput = ({ data, key }: { data: FlowNodeOutputItemType; key: string }) => {
      if (data.id) {
        onChangeNode({
          nodeId,
          type: 'replaceOutput',
          key,
          value: data,
        });
      }
    };

    const onAddOutput = () => {
      const newOutput = {
        ...defaultOutput,
        id: getNanoid(),
      };
      onChangeNode({
        nodeId,
        type: 'addEmptyOutput',
        value: newOutput,
      });
    };

    const onDelOutput = (key: string) => {
      onChangeNode({
        nodeId,
        type: 'delOutput',
        key,
      });
    };

    return !addOutput?.customFieldConfig ? null : (
      <div className="nodrag">
        <div className="nodrag relative mb-2 flex cursor-default items-center">
          <div className="relative font-medium">
            {t((addOutput.label || 'common:core.workflow.Custom outputs') as any)}
          </div>
          {addOutput.description && <QuestionTip title={addOutput.description} icon="" />}
          <div className="flex-1" />
        </div>

        <div className="flex flex-col gap-2">
          {filterAddOutput.map((output) => {
            const type = output.valueType
              ? t(AllFlowValueTypeMap[output.valueType]?.label as any)
              : '-';
            const { key } = output;
            return (
              <div key={output.key}>
                <div className="flex w-full space-x-3">
                  {showValueTypeSelect && (
                    <Select
                      className="w-full"
                      popupClassName="workflow-dropdown"
                      options={valueTypeSelectList.filter(
                        (item) => item.value !== WorkflowIOValueTypeEnum.arrayAny,
                      )}
                      value={type}
                      placeholder={t('core.module.Data Type')}
                      onChange={(e) => {
                        changeOutput({
                          key,
                          data: {
                            ...output,
                            valueType: e as WorkflowIOValueTypeEnum,
                          },
                        });
                      }}
                    />
                  )}

                  {/* key */}
                  <Input
                    className="ml-2 bg-gray-100"
                    placeholder={t('Variable_name')}
                    defaultValue={key}
                    onBlur={(e) => {
                      changeOutput({
                        key,
                        data: {
                          ...output,
                          key: e.target.value,
                          label: e.target.value,
                        },
                      });
                    }}
                  />

                  <Button
                    icon={<MinusCircleOutlined className="group-hover:text-error" />}
                    type="text"
                    className="group"
                    style={{
                      color: 'var(--text-4)',
                    }}
                    onClick={() => onDelOutput(output.key)}
                  />
                </div>
              </div>
            );
          })}
        </div>
        <div className="mb-2 mt-2 flex w-full items-center justify-center">
          <Button icon={<PlusOutlined />} type="text" onClick={onAddOutput}>
            添加输出
          </Button>
        </div>
      </div>
    );
  }, [addOutput, filterAddOutput, showValueTypeSelect, valueTypeSelectList, nodeId, onChangeNode]);

  const RenderCommonOutputs = useMemo(() => {
    const renderOutputs = copyOutputs.filter(
      (item) =>
        item.type !== FlowNodeOutputTypeEnum.dynamic && item.type !== FlowNodeOutputTypeEnum.hidden,
    );
    return (
      <div className="flex flex-col justify-center gap-2">
        {renderOutputs.map((output, i) => {
          return output.label ? (
            <FormLabel
              key={output.key}
              required={output.required}
              className={`relative ${i === renderOutputs.length - 1 ? 'mb-2' : ''}`}
              style={{
                fontWeight: 400,
              }}
            >
              <OutputLabel nodeId={nodeId} output={output} />
            </FormLabel>
          ) : null;
        })}
      </div>
    );
  }, [copyOutputs, nodeId]);

  return (
    <div className="rounded-2xl">
      {RenderDynamicOutputs}
      {RenderCommonOutputs}
    </div>
  );
};

export default React.memo(RenderOutput);
